﻿namespace SharePoint.ImportExport.Core
{
    using System;
    using System.Collections;
    using System.IO;
    using System.Xml;
    using System.Xml.Schema;
    using System.Xml.Serialization;

    /// <summary>
    /// This is the enumeration of datacontainer types
    /// </summary>
    /// <remarks>
    /// </remarks>
    public enum WebPartType
    {
        /// <summary>
        /// Default value used only to ensure that the correct value is set
        /// </summary>
        Undefined,

        /// <summary>
        /// Listview Web part
        /// </summary>
        ListViewWebPart,

        /// <summary>
        /// ListForm Web part
        /// </summary>
        ListFormWebPart,

        /// <summary>
        /// Image Web part
        /// </summary>
        ImageWebPart,

        /// <summary>
        /// Other Web part
        /// </summary>
        OtherWebPart,

        /// <summary>
        /// XsltListViewWebPart
        /// </summary>
        XsltListViewWebPart
    }

    /// <summary>
    /// This is the enumeration of resource types
    /// </summary>
    /// <remarks>
    /// </remarks>
    public enum ResourceType
    {
        /// <summary>
        /// Default value used only to ensure that the correct value is set
        /// </summary>
        Undefined,

        /// <summary>
        /// The resource is a file
        /// </summary>
        File,

        /// <summary>
        /// The resource is a folder
        /// </summary>
        Folder
    }

    /// <summary>
    /// This is the helper class that is used for serializing the property bag of SPFile
    /// </summary>
    /// <example>
    /// <code>
    /// bool ghosted=bool.Parse(file.Properties["vti_hasdefaultcontent"].ToString());
    /// Hashtable ht=new Hashtable();
    /// string Key="Key";
    /// string Value="Value";
    /// ht.Add(Key,Value);
    /// <para></para>
    /// DictionarySerializer DS = new DictionarySerializer(ht);
    /// XmlSerializer xmlser=new XmlSerializer(typeof(DictionarySerializer ),"SPFile.Props");
    /// MemoryStream writer = new MemoryStream();
    /// xmlser.Serialize(writer,DS);
    /// writer.Flush();
    /// </code></example>
    public class DictionarySerializer : IXmlSerializable
    {
        /// <summary>
        /// Internal IDictionary
        /// </summary>
        private IDictionary dictionary;

        /// <summary>
        /// Initializes a new instance of the DictionarySerializer class.
        /// </summary>
        public DictionarySerializer()
        {
            this.dictionary = new Hashtable();
        }

        /// <summary>
        /// Initializes a new instance of the DictionarySerializer class.
        /// </summary>
        /// <param name="ht">Hashtable to serialize</param>
        public DictionarySerializer(Hashtable ht)
        {
            this.dictionary = new Hashtable();
            this.dictionary = ht;
        }

        /// <summary>
        /// Initializes a new instance of the DictionarySerializer class.
        /// </summary>
        /// <param name="dictionary">Internal iDictionary object</param>
        private DictionarySerializer(IDictionary dictionary)
        {
            this.dictionary = dictionary;
        }

        /// <summary>
        /// Gets the underlying dictionary object
        /// </summary>
        public IDictionary Dictionary
        {
            get
            {
                return this.dictionary;
            }
        }

        /// <summary>
        /// Serialization routine
        /// </summary>
        /// <param name="dictionary">Internal dictionary</param>
        /// <param name="stream">Stream to use in serializing</param>
        public static void Serialize(IDictionary dictionary, Stream stream)
        {
            DictionarySerializer ds = new DictionarySerializer(dictionary);
            XmlSerializer xs = new XmlSerializer(typeof(DictionarySerializer));
            xs.Serialize(stream, ds);
        }

        /// <summary>
        /// Deserialization routine
        /// </summary>
        /// <param name="stream">Stream to use in deserialization</param>
        /// <returns>return sn iDictionary object</returns>
        public static IDictionary Deserialize(Stream stream)
        {
            XmlSerializer xs = new XmlSerializer(typeof(DictionarySerializer));
            DictionarySerializer ds = (DictionarySerializer)xs.Deserialize(stream);
            return ds.dictionary;
        }

        /// <summary>
        /// Returns the schema of the internal object
        /// </summary>
        /// <returns>null as this is not implemented</returns>
        XmlSchema IXmlSerializable.GetSchema()
        {
            return null;
        }

        /// <summary>
        /// This reads the xml
        /// </summary>
        /// <param name="reader">XMLReader to read from</param>
        void IXmlSerializable.ReadXml(XmlReader reader)
        {
            reader.Read();
            reader.ReadStartElement("dictionary");
            while (reader.NodeType != XmlNodeType.EndElement)
            {
                reader.ReadStartElement("item");
                string key = reader.ReadElementString("key");
                string value = reader.ReadElementString("value");
                reader.ReadEndElement();
                reader.MoveToContent();
                this.dictionary.Add(key, value);
            }
        }

        /// <summary>
        /// This writes the xml
        /// </summary>
        /// <param name="writer">XMLWriter to write to</param>
        void IXmlSerializable.WriteXml(XmlWriter writer)
        {
            writer.WriteStartElement("dictionary");
            foreach (object key in this.dictionary.Keys)
            {
                object value = this.dictionary[key];
                writer.WriteStartElement("item");
                writer.WriteElementString("key", key.ToString());
                writer.WriteElementString("value", value.ToString());
                writer.WriteEndElement();
            }

            writer.WriteEndElement();
        }

        /// <summary>
        /// Gets a property from the propertycollection
        /// </summary>
        /// <param name="key">Name of parameter</param>
        /// <returns>The property specified by the key parameter</returns>
        public string GetProperty(string key)
        {
            return this.dictionary[key].ToString();
        }
    }

    /// <summary>
    /// This is the class storing the design elements of teh site
    /// </summary>
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
    public class DesignElement
    {
        /// <summary>
        /// This is the collection of pages
        /// </summary>
        private PagesCollection pages;

        /// <summary>
        /// This is the collection of resources
        /// </summary>
        private ResourcesCollection resources;

        /// <summary>
        /// Initializes a new instance of the DesignElements class.
        /// </summary>
        /// <remarks>Instantiates the collection variable</remarks>
        public DesignElement()
        {
            this.pages = new PagesCollection();
            this.resources = new ResourcesCollection();
        }

        /// <summary>
        /// Gets or sets the pages collection
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("page", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public PagesCollection Pages
        {
            get
            {
                return this.pages;
            }
            set
            {
                this.pages = value;
            }
        }

        /// <summary>
        /// Gets or sets the resources collection
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("resource", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public ResourcesCollection Resources
        {
            get
            {
                return this.resources;
            }
            set
            {
                this.resources = value;
            }
        }
    }

    /// <summary>
    /// This is the class implementing the PagesCollection collection
    /// </summary>
    public class PagesCollection : ICollection
    {
        /// <summary>
        /// This is the internal collection of pages
        /// </summary>
        private ArrayList pagesCollection;

        /// <summary>
        /// Initializes a new instance of the PagesCollection class
        /// </summary>
        /// <remarks>Instantiates the collection variables</remarks>
        public PagesCollection()
        {
            this.pagesCollection = new ArrayList();
        }

        #region ICollection Members
        /// <summary>
        /// Gets a value indicating whether access to the ArrayList is synchronized (thread-safe).
        /// </summary>
        /// <remarks>
        /// To guarantee the thread safety of the ArrayList, all operations must be done through the wrapper returned by the Synchronized method.
        /// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or catch the exceptions resulting from changes made by other threads.
        /// </remarks>
        public bool IsSynchronized
        {
            get
            {
                return this.pagesCollection.IsSynchronized;
            }
        }

        /// <summary>
        /// Gets a value indicating the number of objects in the collection. Read-only.
        /// </summary>
        public int Count
        {
            get
            {
                return this.pagesCollection.Count;
            }
        }

        /// <summary>
        /// Gets an object that can be used to synchronize access to the ArrayList.
        /// </summary>
        /// <remarks>
        /// To create a synchronized version of the ArrayList, use the Synchronized method. However, derived classes can provide their own synchronized version of the ArrayList using the SyncRoot property. The synchronizing code must perform operations on the SyncRoot of the ArrayList, not directly on the ArrayList. This ensures proper operation of collections that are derived from other objects. 
        /// Specifically, it maintains proper synchronization with other threads that might be simultaneously modifying the ArrayList object.
        /// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or 
        /// catch the exceptions resulting from changes made by other threads.
        /// </remarks>
        public object SyncRoot
        {
            get
            {
                return this.pagesCollection.SyncRoot;
            }
        }

        /// <summary>
        /// Gets the element at the specified index.
        /// </summary>
        /// <param name="index">The index of the item</param>
        public Page this[int index]
        {
            get
            {
                return (Page)this.pagesCollection[index];
            }
        }

        /// <summary>
        /// Copies the entire ArrayList to a compatible one-dimensional Array, starting at the specified index of the target array.
        /// </summary>
        /// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
        /// <param name="index">The zero-based index in array at which copying begins</param>
        public void CopyTo(Page[] a, int index)
        {
            this.pagesCollection.CopyTo(a, index);
        }

        /// <summary>
        /// Copies the entire ArrayList to a compatible one-dimensional Array, starting at the specified index of the target array.
        /// </summary>
        /// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
        /// <param name="index">The zero-based index in array at which copying begins</param>
        public void CopyTo(Array a, int index)
        {
            this.pagesCollection.CopyTo(a, index);
        }

        #endregion

        #region IEnumerable Members

        /// <summary>
        /// Returns an enumerator that can iterate through the ArrayList.
        /// </summary>
        /// <returns>The Enumerator of the collection</returns>
        public IEnumerator GetEnumerator()
        {
            return this.pagesCollection.GetEnumerator();
        }

        #endregion

        /// <summary>
        /// Adds an object to the end of the ArrayList.
        /// </summary>
        /// <param name="newPage">New Page to be added to the list</param>
        public void Add(Page newPage)
        {
            this.pagesCollection.Add(newPage);
        }
    }

    /// <summary>
    /// This is the class representing a page in SharePoint
    /// </summary>
    public class Page
    {
        /// <summary>
        /// This will contain all the extra properties not included in the xml schema
        /// </summary>
        private string propertyBag;

        /// <summary>
        /// This is the Url of the page
        /// </summary>
        private string url;

        /// <summary>
        /// This is the filaname of the page
        /// </summary>
        private string file;

        /// <summary>
        /// This is the collection of Web parts associated to the page
        /// </summary>
        private WebPartsCollection webParts;

        /// <summary>
        /// This is the collection of all the metadata associated to the item
        /// </summary>
        private ItemsFieldsCollection fields;

        /// <summary>
        /// Initializes a new instance of the Page class
        /// </summary>
        public Page()
        {
            this.webParts = new WebPartsCollection();
            this.fields = new ItemsFieldsCollection();
        }

        /// <summary>
        /// Gets or sets the url of the page
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string URL
        {
            get
            {
                return this.url;
            }

            set
            {
                this.url = value;
            }
        }

        /// <summary>
        /// Gets or sets the filename of the page
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("file", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string FileName
        {
            get
            {
                return this.file;
            }

            set
            {
                this.file = value;
            }
        }

        /// <summary>
        /// Gets the web part collection
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("webpart", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public WebPartsCollection WebParts
        {
            get
            {
                return this.webParts;
            }
        }

        /// <summary>
        /// Gets or sets the value that will contain all the extra properties not included in the xml schema
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("propertybag", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string PropertyBag
        {
            get
            {
                return this.propertyBag;
            }

            set
            {
                this.propertyBag = value;
            }
        }

        /// <summary>
        /// Gets the collection of properties associated to the item
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("field", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public ItemsFieldsCollection Fields
        {
            get
            {
                return this.fields;
            }
        }
    }

    /// <summary>
    /// This is the class implementing the WebPartsCollection collection
    /// </summary>
    public class WebPartsCollection : ICollection
    {
        /// <summary>
        /// This is the internal array of Web Parts
        /// </summary>
        private ArrayList webParts;

        /// <summary>
        /// Initializes a new instance of the WebPartsCollection class
        /// </summary>
        /// <remarks>Instantiates the WebParts member</remarks>
        public WebPartsCollection()
        {
            this.webParts = new ArrayList();
        }

        #region ICollection Members
        /// <summary>
        /// Gets a value indicating whether access to the ArrayList is synchronized (thread-safe).
        /// </summary>
        /// <remarks>
        /// To guarantee the thread safety of the ArrayList, all operations must be done through the wrapper returned by the Synchronized method.
        /// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or catch the exceptions resulting from changes made by other threads.
        /// </remarks>
        public bool IsSynchronized
        {
            get
            {
                return this.webParts.IsSynchronized;
            }
        }

        /// <summary>
        /// Gets a value indicating the number of objects in the collection. Read-only.
        /// </summary>
        public int Count
        {
            get
            {
                return this.webParts.Count;
            }
        }

        /// <summary>
        /// Gets an object that can be used to synchronize access to the ArrayList.
        /// </summary>
        /// <remarks>
        /// To create a synchronized version of the ArrayList, use the Synchronized method. However, derived classes can provide their own synchronized version of the ArrayList using the SyncRoot property. The synchronizing code must perform operations on the SyncRoot of the ArrayList, not directly on the ArrayList. This ensures proper operation of collections that are derived from other objects. 
        /// Specifically, it maintains proper synchronization with other threads that might be simultaneously modifying the ArrayList object.
        /// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or 
        /// catch the exceptions resulting from changes made by other threads.
        /// </remarks>
        public object SyncRoot
        {
            get
            {
                return this.webParts.SyncRoot;
            }
        }

        /// <summary>
        /// Gets the element at the specified index.
        /// </summary>
        /// <param name="index">The index of the item</param>
        public WebPart this[int index]
        {
            get
            {
                return (WebPart)this.webParts[index];
            }
        }

        /// <summary>
        /// Copies the entire ArrayList to a compatible one-dimensional Array, starting at the specified index of the target array.
        /// </summary>
        /// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
        /// <param name="index">The zero-based index in array at which copying begins</param>
        public void CopyTo(Resource[] a, int index)
        {
            this.webParts.CopyTo(a, index);
        }

        /// <summary>
        /// Copies the entire ArrayList to a compatible one-dimensional Array, starting at the specified index of the target array.
        /// </summary>
        /// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
        /// <param name="index">The zero-based index in array at which copying begins</param>
        public void CopyTo(Array a, int index)
        {
            this.webParts.CopyTo(a, index);
        }

        #endregion

        #region IEnumerable Members

        /// <summary>
        /// Returns an enumerator that can iterate through the ArrayList.
        /// </summary>
        /// <returns>The Enumerator of the collection</returns>
        public IEnumerator GetEnumerator()
        {
            return this.webParts.GetEnumerator();
        }

        #endregion
        /// <summary>
        /// Adds an object to the end of the ArrayList.
        /// </summary>
        /// <param name="newPart">New Web Part to be added to the list</param>
        public void Add(WebPart newPart)
        {
            this.webParts.Add(newPart);
        }
    }

    /// <summary>
    /// This is the class representing a Web Part
    /// </summary>
    public class WebPart
    {
        /// <summary>
        /// This is the Web Part string
        /// </summary>
        private string dwp;

        /// <summary>
        /// This is the settings info of the Web Part
        /// </summary>
        private string settings;

        /// <summary>
        /// This is the ID of the Zone where the web part is stored
        /// </summary>
        private string zoneID;

        /// <summary>
        /// This is the title of the Web Part
        /// </summary>
        private string title;

        /// <summary>
        /// This is the number indicating the order of the Web Parts in the zone
        /// </summary>
        private int partOrder;

        /// <summary>
        /// This is the type of the Web Part
        /// </summary>
        private WebPartType partType;

        /// <summary>
        /// This is a flag indicating whether the Web Part should be included on the page or not
        /// </summary>
        private bool isIncluded = true;

        /// <summary>
        /// This controls the visibility of the Web Part
        /// </summary>
        private bool isVisible = true;

        /// <summary>
        /// The ConnectionID property is the GUID that is used internally by the Web Part infrastructure as the unique identifier of a Web Part connection
        /// </summary>
        private Guid connectionID = Guid.Empty;

        /// <summary>
        /// The Connections property specified the connection information that is stored with a connected Web Part.
        /// </summary>
        private string connections = String.Empty;

        /// <summary>
        /// This is the ID of the Web Part
        /// </summary>
        private string id;

        /// <summary>
        /// Gets or sets the Web Part string
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string DWP
        {
            get
            {
                return this.dwp;
            }

            set
            {
                this.dwp = value;
            }
        }

        /// <summary>
        /// Gets or sets the settings of the Web Part
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string Settings
        {
            get
            {
                return this.settings;
            }

            set
            {
                this.settings = value;
            }
        }

        /// <summary>
        /// Gets or sets the Zone ID to use
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string ZoneID
        {
            get
            {
                return this.zoneID;
            }

            set
            {
                this.zoneID = value;
            }
        }

        /// <summary>
        /// Gets or sets the title of the Web Part
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string Title
        {
            get
            {
                return this.title;
            }

            set
            {
                this.title = value;
            }
        }

        /// <summary>
        /// Gets or sets the partorder
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public int PartOrder
        {
            get
            {
                return this.partOrder;
            }

            set
            {
                this.partOrder = value;
            }
        }

        /// <summary>
        /// Gets or sets the type of the Web PArt
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public WebPartType PartType
        {
            get
            {
                return this.partType;
            }

            set
            {
                this.partType = value;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether the Web Part is included on the page or not
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public bool IsIncluded
        {
            get
            {
                return this.isIncluded;
            }

            set
            {
                this.isIncluded = value;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether the Web Part is visible or not
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public bool IsVisible
        {
            get
            {
                return this.isVisible;
            }

            set
            {
                this.isVisible = value;
            }
        }

        /// <summary>
        /// Gets or sets the connection ID that the Web Part uses
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public Guid ConnectionID
        {
            get
            {
                return this.connectionID;
            }

            set
            {
                this.connectionID = value;
            }
        }

        /// <summary>
        /// Gets or sets the Connections string
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("Connections", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string WebPartConnections
        {
            get
            {
                return this.connections;
            }

            set
            {
                this.connections = value;
            }
        }

        /// <summary>
        /// Gets or sets the Web Part string
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string ID
        {
            get
            {
                return this.id;
            }

            set
            {
                this.id = value;
            }
        }

    }

    /// <summary>
    /// This is the class implementing the Resources collection
    /// </summary>
    public class ResourcesCollection : ICollection
    {
        /// <summary>
        /// This is the internal collection of resources
        /// </summary>
        private ArrayList resources;

        /// <summary>
        /// Initializes a new instance of the ResourcesCollection class
        /// </summary>
        /// <remarks>Instantiates the Resources member</remarks>
        public ResourcesCollection()
        {
            this.resources = new ArrayList();
        }

        #region ICollection Members
        /// <summary>
        /// Gets a value indicating whether access to the ArrayList is synchronized (thread-safe).
        /// </summary>
        /// <remarks>
        /// To guarantee the thread safety of the ArrayList, all operations must be done through the wrapper returned by the Synchronized method.
        /// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or catch the exceptions resulting from changes made by other threads.
        /// </remarks>
        public bool IsSynchronized
        {
            get
            {
                return this.resources.IsSynchronized;
            }
        }

        /// <summary>
        /// Gets a value indicating the number of objects in the collection. Read-only.
        /// </summary>
        public int Count
        {
            get
            {
                return this.resources.Count;
            }
        }

        /// <summary>
        /// Gets an object that can be used to synchronize access to the ArrayList.
        /// </summary>
        /// <remarks>
        /// To create a synchronized version of the ArrayList, use the Synchronized method. However, derived classes can provide their own synchronized version of the ArrayList using the SyncRoot property. The synchronizing code must perform operations on the SyncRoot of the ArrayList, not directly on the ArrayList. This ensures proper operation of collections that are derived from other objects. 
        /// Specifically, it maintains proper synchronization with other threads that might be simultaneously modifying the ArrayList object.
        /// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or 
        /// catch the exceptions resulting from changes made by other threads.
        /// </remarks>
        public object SyncRoot
        {
            get
            {
                return this.resources.SyncRoot;
            }
        }

        /// <summary>
        /// Gets the element at the specified index.
        /// </summary>
        /// <param name="index">The index of the item</param>
        public Resource this[int index]
        {
            get
            {
                return (Resource)this.resources[index];
            }
        }

        /// <summary>
        /// Copies the entire ArrayList to a compatible one-dimensional Array, starting at the specified index of the target array.
        /// </summary>
        /// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
        /// <param name="index">The zero-based index in array at which copying begins</param>
        public void CopyTo(Resource[] a, int index)
        {
            this.resources.CopyTo(a, index);
        }

        /// <summary>
        /// Copies the entire ArrayList to a compatible one-dimensional Array, starting at the specified index of the target array.
        /// </summary>
        /// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
        /// <param name="index">The zero-based index in array at which copying begins</param>
        public void CopyTo(Array a, int index)
        {
            this.resources.CopyTo(a, index);
        }

        #endregion

        #region IEnumerable Members

        /// <summary>
        /// Returns an enumerator that can iterate through the ArrayList.
        /// </summary>
        /// <returns>The Enumerator of the collection</returns>
        public IEnumerator GetEnumerator()
        {
            return this.resources.GetEnumerator();
        }

        #endregion
        /// <summary>
        /// Adds an object to the end of the ArrayList.
        /// </summary>
        /// <param name="newResource">New Resource to be added to the list</param>
        public void Add(Resource newResource)
        {
            this.resources.Add(newResource);
        }
    }

    /// <summary>
    /// This is the class representing a resource in SharePoint
    /// </summary>
    public class Resource
    {
        /// <summary>
        /// This is the URL of the resource
        /// </summary>
        private string url;

        /// <summary>
        /// This is the type of resource
        /// </summary>
        private ResourceType dataType = ResourceType.Undefined;

        /// <summary>
        /// This is the filename of the resource
        /// </summary>
        private string file;

        /// <summary>
        /// Gets or sets the url of the resource
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string URL
        {
            get
            {
                return this.url;
            }

            set
            {
                this.url = value;
            }
        }

        /// <summary>
        /// Gets or sets the type of the resource
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public ResourceType DataType
        {
            get
            {
                return this.dataType;
            }

            set
            {
                this.dataType = value;
            }
        }

        /// <summary>
        /// Gets or sets the filename of the resource
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string File
        {
            get
            {
                return this.file;
            }

            set
            {
                this.file = value;
            }
        }
    }
}